package com.zondy.mapgis.android.view;


import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Rect;
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SoundEffectConstants;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewGroup;
import android.view.accessibility.AccessibilityEvent;
import android.widget.FrameLayout;

import com.zondy.mapgis.explorer.R;

public class TotalViewSlidingDrawerBK extends ViewGroup {

	/**
	 * 一个不受surfaceView干扰的Slidingdrawer代码
	 * 
	 */

	public static final int ORIENTATION_HORIZONTAL = 0;
	public static final int ORIENTATION_VERTICAL = 1;

	private static final int TAP_THRESHOLD = 6;
	private static final float MAXIMUM_TAP_VELOCITY = 100.0f;
	private static final float MAXIMUM_MINOR_VELOCITY = 150.0f;
	private static final float MAXIMUM_MAJOR_VELOCITY = 200.0f;
	private static final float MAXIMUM_ACCELERATION = 2000.0f;
	private static final int VELOCITY_UNITS = 1000;
	private static final int MSG_ANIMATE = 1000;
	private static final int ANIMATION_FRAME_DURATION = 1000 / 60;

	private static final int EXPANDED_FULL_OPEN = -10001;
	private static final int COLLAPSED_FULL_CLOSED = -10002;
	private static final int FIRST_DRAWER_OPEN = -10003;

	private final int mContentId;
	private final int mfirstcontentHeight;

	private View mContentView;
	private int mSecondcontentHeight;
	private FrameLayout ViewLocation;

	private final Rect mFrame = new Rect();
	private final Rect mInvalidate = new Rect();
	private boolean mTracking;
	private boolean mLocked;

	private VelocityTracker mVelocityTracker;

	private boolean mVertical;
	private int mExpanded;
	private int mBottomOffset;
	private int mTopOffset;
	private int mHandleHeight;
	private int mHandleWidth;

	private boolean TouchThough = true;

	private OnDrawerOpenListener mOnDrawerOpenListener;
	private OnDrawerCloseListener mOnDrawerCloseListener;
	private OnDrawerScrollListener mOnDrawerScrollListener;
	private onHalfOpenListener mOnHalfOpenListener;

	private final Handler mHandler = new SlidingHandler();
	private float mAnimatedAcceleration;
	private float mAnimatedVelocity;
	private float mAnimationPosition;
	private long mAnimationLastTime;
	private long mCurrentAnimationTime;
	private int mTouchDelta;
	private boolean mAnimating;
	private boolean mAllowSingleTap;
	private boolean mAnimateOnClick;

	private final int mTapThreshold;
	private final int mMaximumTapVelocity;
	private final int mMaximumMinorVelocity;
	private final int mMaximumMajorVelocity;
	private final int mMaximumAcceleration;
	private final int mVelocityUnits;

	/**
	 * Callback invoked when the drawer is opened.
	 */
	public static interface OnDrawerOpenListener {
		/**
		 * Invoked when the drawer becomes fully open.
		 */
		public void onDrawerOpened();
	}

	/**
	 * Callback invoked when the drawer is closed.
	 */
	public static interface OnDrawerCloseListener {
		/**
		 * Invoked when the drawer becomes fully closed.
		 */
		public void onDrawerClosed();
	}

	/**
	 * Callback invoked when the drawer is scrolled.
	 */
	public static interface OnDrawerScrollListener {
		/**
		 * Invoked when the user starts dragging/flinging the drawer's handle.
		 */
		public void onScrollStarted();

		/**
		 * Invoked when the user stops dragging/flinging the drawer's handle.
		 */
		public void onScrollEnded();
	}

	public static interface onHalfOpenListener {
		public void onHalfOpen();
	}

	public void SetOnHalfOpenListener(onHalfOpenListener l) {
		mOnHalfOpenListener = l;
	}

	/**
	 * Creates a new SlidingDrawer from a specified set of attributes defined in
	 * XML.
	 * 
	 * @param context
	 *            The application's environment.
	 * @param attrs
	 *            The attributes defined in XML.
	 */
	public TotalViewSlidingDrawerBK(Context context, AttributeSet attrs) {
		this(context, attrs, 0);
	}

	/**
	 * Creates a new SlidingDrawer from a specified set of attributes defined in
	 * XML.
	 * 
	 * @param context
	 *            The application's environment.
	 * @param attrs
	 *            The attributes defined in XML.
	 * @param defStyle
	 *            The style to apply to this widget.
	 */
	public TotalViewSlidingDrawerBK(Context context, AttributeSet attrs,
			int defStyle) {
		super(context, attrs, defStyle);
		TypedArray a = context.obtainStyledAttributes(attrs,
				R.styleable.TotalViewSlidingDrawer, defStyle, 0);

		mVertical = true;
		mBottomOffset = 0;
		mTopOffset = 0;
		mAllowSingleTap = true;
		mAnimateOnClick = true;
		mfirstcontentHeight = (int) a.getDimension(
				R.styleable.TotalViewSlidingDrawer_firstheight, 100.0f);
		int ContentId = a.getResourceId(
				R.styleable.TotalViewSlidingDrawer_containview, 0);
		if (ContentId == 0) {
			throw new IllegalArgumentException(
					"The view attribute is required and must refer "
							+ "to a valid child.");
		}
		int handlercontentHeight = (int) a.getDimension(
				R.styleable.TotalViewSlidingDrawer_handlerheight, 100.0f);
		mContentId = ContentId;
		mHandleHeight = handlercontentHeight;

		final float density = getResources().getDisplayMetrics().density;
		mTapThreshold = (int) (TAP_THRESHOLD * density + 0.5f);
		mMaximumTapVelocity = (int) (MAXIMUM_TAP_VELOCITY * density + 0.5f);
		mMaximumMinorVelocity = (int) (MAXIMUM_MINOR_VELOCITY * density + 0.5f);
		mMaximumMajorVelocity = (int) (MAXIMUM_MAJOR_VELOCITY * density + 0.5f);
		mMaximumAcceleration = (int) (MAXIMUM_ACCELERATION * density + 0.5f);
		mVelocityUnits = (int) (VELOCITY_UNITS * density + 0.5f);

		a.recycle();

		view = new View(getContext());

		addView(view, 0);
		setAlwaysDrawnWithCacheEnabled(false);
	}

	public void SetTouchThoughEnable(Boolean e) {
		TouchThough = e;
	}

	@Override
	protected void onFinishInflate() {
		Log.i("tag", "===========onFinishInflate===========");
		mContentView = findViewById(mContentId);
		if (mContentView == null) {
			throw new IllegalArgumentException(
					"The handle attribute is must refer to an"
							+ " existing child.");
		}

		mContentView.setOnClickListener(new DrawerToggler());
		super.onFinishInflate();

	}

	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

		super.onMeasure(widthMeasureSpec, heightMeasureSpec);
		Log.i("tag", "===========onMeasure===========");
		int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
		int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);

		int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
		int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);

		if (widthSpecMode == MeasureSpec.UNSPECIFIED
				|| heightSpecMode == MeasureSpec.UNSPECIFIED) {
			throw new RuntimeException(
					"SlidingDrawer cannot have UNSPECIFIED dimensions");
		}

		final View Content = mContentView;
		measureChild(Content, widthMeasureSpec, heightMeasureSpec);
		setMeasuredDimension(widthSpecSize, heightSpecSize);
	}

	@Override
	protected void dispatchDraw(Canvas canvas) {
		super.dispatchDraw(canvas);
	}

	private int ViewWidth;
	private int ViewHeight;

	private View view;

	@Override
	protected void onLayout(boolean changed, int l, int t, int r, int b) {
		Log.i("tag", "===========onLayout===========");
		/**
		 * 总之，这个代码是用来onlayout的，为了兼容多种子视图，在google的源码上做修改 下面这句的错误让我调试了半天 默哀下。
		 * 
		 * @author shisongran
		 */
		// if (mTracking) {
		// return;
		// }
		final int secondheight = getBottom() - getTop() - mHandleHeight
				- mTopOffset - mfirstcontentHeight;
		mSecondcontentHeight = secondheight;

		final int width = r - l;
		final int height = b - t;

		final View Content = mContentView;

		int childWidth = Content.getMeasuredWidth();
		int childHeight = Content.getMeasuredHeight();

		int childLeft;
		int childTop;

		childLeft = (width - childWidth) / 2;
		childTop = mExpanded == 1 ? mTopOffset : height - childHeight
				+ mBottomOffset;
		switch (mExpanded) {
		case 0:
			childTop = mfirstcontentHeight + secondheight;
			break;
		case 1:
			childTop = mTopOffset;
			break;
		case 2:
			childTop = height - mHandleHeight + mBottomOffset
					- mfirstcontentHeight;
			break;
		default:
			break;
		}
		ViewWidth = childWidth;
		ViewHeight = childHeight;
		view.setBackgroundColor(Color.TRANSPARENT);
		view.layout(childLeft, childTop - 1280, childLeft + childWidth,
				childTop);
		Content.layout(childLeft, childTop, childLeft + childWidth, childTop
				+ childHeight + mSecondcontentHeight + mfirstcontentHeight);
		mHandleWidth = Content.getWidth();
	}

	private int VorH = 0;

	public interface onActionStartListener {
		public static final int ACTION_H = -1;
		public static final int ACTION_V = 1;

		public void onActionStart(int Forwards);
	}

	private onActionStartListener monActionStartListener = null;

	public void setonActionStartListener(onActionStartListener l) {
		monActionStartListener = l;
	}

	@Override
	public boolean onInterceptTouchEvent(MotionEvent event) {

		Log.i(getClass().getName(), "onInterceptTouchEvent");

		if (mContentView.getVisibility() == View.VISIBLE) {
			final int action = event.getAction();

			float x = event.getX();
			float y = event.getY();

			final Rect frame = mFrame;
			final View Content = mContentView;

			Content.getHitRect(frame);

			if (!mTracking && !frame.contains((int) x, (int) y)) {
				return false;
			}
			
			if (action == MotionEvent.ACTION_DOWN) {
				// mTracking = true;

				//Content.setPressed(true);
				// Must be called before prepareTracking()
				prepareContent();

				// Must be called after prepareContent()

				if (mVertical) {
					final int top = Content.getTop();
					mTouchDelta = (int) y - top;
					prepareTracking(top);
				} else {
					final int left = Content.getLeft();
					mTouchDelta = (int) x - left;
					prepareTracking(left);
				}

			}
			// if(frame.contains((int) x, (int) y))
			mVelocityTracker.addMovement(event);
			if (VorH == 0) {
				final VelocityTracker velocityTracker = mVelocityTracker;
				velocityTracker.computeCurrentVelocity(mVelocityUnits);
				final float Xv = velocityTracker.getXVelocity();
				final float Yv = velocityTracker.getYVelocity();
				if (Math.abs(Xv) != Math.abs(Yv)
						&& (Math.abs(Xv) > 2 || Math.abs(Yv) > 2)) {
					VorH = Math.abs(Yv) > Math.abs(Xv) ? 1 : -1;
					if (monActionStartListener != null)
						monActionStartListener.onActionStart(VorH);
					if (VorH == 1)
						mTracking = true;
				}
			}

			if (mLocked) {
				return false;
			}

			if (mTracking) {
				// mVelocityTracker.addMovement(event);
				if (VorH == 1) {
					if (mOnDrawerScrollListener != null) {
						mOnDrawerScrollListener.onScrollStarted();
					}
					return true;

				}
			}
			if (action == MotionEvent.ACTION_UP
					|| action == MotionEvent.ACTION_CANCEL) {
				VorH = 0;
			}
		}
		return false;
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {

		Log.i(getClass().getName(), "onTouchEvent");

		if (mLocked) {
			return true;
		}
		final int action = event.getAction();

		if (mTracking) {
			mVelocityTracker.addMovement(event);
			switch (action) {
			case MotionEvent.ACTION_MOVE:
				moveHandle((int) (mVertical ? event.getY() : event.getX())
						- mTouchDelta);
				break;
			case MotionEvent.ACTION_UP:
			case MotionEvent.ACTION_CANCEL: {
				final VelocityTracker velocityTracker = mVelocityTracker;
				velocityTracker.computeCurrentVelocity(mVelocityUnits);

				float yVelocity = velocityTracker.getYVelocity();
				float xVelocity = velocityTracker.getXVelocity();
				boolean negative;

				final boolean vertical = mVertical;
				if (vertical) {
					negative = yVelocity < 0;
					if (xVelocity < 0) {
						xVelocity = -xVelocity;
					}
					if (xVelocity > mMaximumMinorVelocity) {
						xVelocity = mMaximumMinorVelocity;
					}
				} else {
					negative = xVelocity < 0;
					if (yVelocity < 0) {
						yVelocity = -yVelocity;
					}
					if (yVelocity > mMaximumMinorVelocity) {
						yVelocity = mMaximumMinorVelocity;
					}
				}

				float velocity = (float) Math.hypot(xVelocity, yVelocity);
				if (negative) {
					velocity = -velocity;
				}

				final int top = mContentView.getTop();
				final int left = mContentView.getLeft();

				if (Math.abs(velocity) < mMaximumTapVelocity) {
					if ((mExpanded == 1 && top < mTapThreshold + mTopOffset)
							|| (mExpanded == 0 && top > mBottomOffset
									+ getBottom() - getTop() - mHandleHeight
									- mTapThreshold) || mExpanded == 2) {
						if (mAllowSingleTap) {
							playSoundEffect(SoundEffectConstants.CLICK);
							switch (mExpanded) {
							case 0: // animateOpen(vertical ? top : left);
								animateSecondOpen(vertical ? top : left);
								break;
							case 1:
								animateClose(vertical ? top : left);
								break;
							case 2:
								animateOpen(vertical ? top : left);
								break;
							default:
								break;

							}
						} else {
							performFling(vertical ? top : left, velocity, false);
						}

					} else {
						performFling(vertical ? top : left, velocity, false);
					}
				} else {
					performFling(vertical ? top : left, velocity, false);
				}
			}
				break;
			}
		}
		if (VorH == 0)
			return false;
		if (action == MotionEvent.ACTION_UP
				|| action == MotionEvent.ACTION_CANCEL) {
			VorH = 0;
		}

		return mTracking || mAnimating || super.onTouchEvent(event);
	}

	private void animateClose(int position) {
		prepareTracking(position);
		performFling(position, mMaximumAcceleration, true);
	}

	private void animateSecondOpen(int position) {
		prepareTracking(position);
		performFling(position, -mMaximumAcceleration, true);
	}

	private void animateOpen(int position) {
		prepareTracking(position);
		performFling(position, -mMaximumAcceleration, true);
	}

	private void performFling(int position, float velocity, boolean always) {
		mAnimationPosition = position;
		mAnimatedVelocity = velocity;
		switch (mExpanded) {
		case 0:
			if (!always
					&& (velocity > mMaximumMajorVelocity || (position > (mVertical ? getHeight()
							: getWidth()) / 2 && velocity > -mMaximumMajorVelocity))) {
				// We are collapsed, and they moved enough to allow us to
				// expand.
				mAnimatedAcceleration = mMaximumAcceleration;
				if (velocity < 0) {
					mAnimatedVelocity = 0;
				}
			} else {
				// We are collapsed, but they didn't move sufficiently to cause
				// us to retract. Animate back to the collapsed position.
				mAnimatedAcceleration = -mMaximumAcceleration;
				if (velocity > 0) {
					mAnimatedVelocity = 0;
				}
			}
			break;
		case 1:
			if (always
					|| (velocity > mMaximumMajorVelocity || (position > mTopOffset
							+ (mVertical ? mHandleHeight : mHandleWidth) && velocity > -mMaximumMajorVelocity))) {
				// We are expanded, but they didn't move sufficiently to cause
				// us to retract. Animate back to the expanded position.
				mAnimatedAcceleration = mMaximumAcceleration;
				if (velocity < 0) {
					mAnimatedVelocity = 0;
				}
			} else {
				// We are expanded and are now going to animate away.
				mAnimatedAcceleration = -mMaximumAcceleration;
				if (velocity > 0) {
					mAnimatedVelocity = 0;
				}
			}
			break;
		case 2:
			if (!always
					&& (velocity > mMaximumMajorVelocity || (position > (mVertical ? getHeight()
							: getWidth()) / 2 && velocity > -mMaximumMajorVelocity))) {
				// We are collapsed, and they moved enough to allow us to
				// expand.
				mAnimatedAcceleration = mMaximumAcceleration;
				if (velocity < 0) {
					mAnimatedVelocity = 0;
				}
			} else {
				// We are collapsed, but they didn't move sufficiently to cause
				// us to retract. Animate back to the collapsed position.
				mAnimatedAcceleration = -mMaximumAcceleration;
				if (velocity > 0) {
					mAnimatedVelocity = 0;
				}
			}
			break;
		default:
			break;
		}
		long now = SystemClock.uptimeMillis();
		mAnimationLastTime = now;
		mCurrentAnimationTime = now + ANIMATION_FRAME_DURATION;
		mAnimating = true;
		mHandler.removeMessages(MSG_ANIMATE);
		mHandler.sendMessageAtTime(mHandler.obtainMessage(MSG_ANIMATE),
				mCurrentAnimationTime);
		stopTracking();
	}

	private void prepareTracking(int position) {
		mTracking = true;
		mVelocityTracker = VelocityTracker.obtain();
		// boolean opening = mExpanded==0;
		long now = 0;
		switch (mExpanded) {
		case 0:
			mAnimatedAcceleration = mMaximumAcceleration;
			mAnimatedVelocity = mMaximumMajorVelocity;
			mAnimationPosition = mBottomOffset
					+ (mVertical ? getHeight() - mHandleHeight : getWidth()
							- mHandleWidth);
			moveHandle((int) mAnimationPosition);
			mAnimating = true;
			mHandler.removeMessages(MSG_ANIMATE);
			now = SystemClock.uptimeMillis();
			mAnimationLastTime = now;
			mCurrentAnimationTime = now + ANIMATION_FRAME_DURATION;
			mAnimating = true;
			break;
		case 1:
			if (mAnimating) {
				mAnimating = false;
				mHandler.removeMessages(MSG_ANIMATE);
			}
			moveHandle(position);
			break;
		case 2:
			mAnimatedAcceleration = mMaximumAcceleration;
			mAnimatedVelocity = mMaximumMajorVelocity;
			mAnimationPosition = mBottomOffset
					+ (mVertical ? getHeight() - mHandleHeight
							- mfirstcontentHeight : getWidth() - mHandleWidth);
			moveHandle((int) mAnimationPosition);
			mAnimating = true;
			mHandler.removeMessages(MSG_ANIMATE);
			now = SystemClock.uptimeMillis();
			mAnimationLastTime = now;
			mCurrentAnimationTime = now + ANIMATION_FRAME_DURATION;
			mAnimating = true;
			break;
		default:
			break;
		}
	}

	private void moveHandle(int position) {
		final View Content = mContentView;
		int secondheight = getBottom() - getTop() - mHandleHeight - mTopOffset
				- mfirstcontentHeight;
		if (mVertical) {
			if (position == EXPANDED_FULL_OPEN) {
				final int d = mTopOffset - Content.getTop();
				view.offsetTopAndBottom(d);
				Content.offsetTopAndBottom(d);
				invalidate();
			} else if (position == COLLAPSED_FULL_CLOSED) {
				final int d = mBottomOffset + getBottom() - getTop()
						- mHandleHeight - Content.getTop();
				view.offsetTopAndBottom(d);
				Content.offsetTopAndBottom(d);
				invalidate();
			} else if (position == FIRST_DRAWER_OPEN) {
				final int d = mTopOffset - Content.getTop() + secondheight;
				Content.offsetTopAndBottom(d);
				view.offsetTopAndBottom(d);
				invalidate();
			} else {
				final int top = Content.getTop();
				int deltaY = position - top;
				if (position < mTopOffset) {
					deltaY = mTopOffset - top;
				} else if (deltaY > mBottomOffset + getBottom() - getTop()
						- mHandleHeight - top) {
					deltaY = mBottomOffset + getBottom() - getTop()
							- mHandleHeight - top;
				}
				Content.offsetTopAndBottom(deltaY);
				view.offsetTopAndBottom(deltaY);

				final Rect frame = mFrame;
				final Rect region = mInvalidate;

				Content.getHitRect(frame);
				region.set(frame);

				region.union(frame.left, frame.top - deltaY, frame.right,
						frame.bottom - deltaY);
				region.union(0, frame.bottom - deltaY, getWidth(), frame.bottom
						- deltaY + mfirstcontentHeight + secondheight);

				invalidate(region);
			}
		}
	}

	private void prepareContent() {
		if (mAnimating) {
			return;
		}
	}

	private void stopTracking() {
		mContentView.setPressed(false);
		mTracking = false;

		if (mOnDrawerScrollListener != null) {
			mOnDrawerScrollListener.onScrollEnded();
		}

		if (mVelocityTracker != null) {
			mVelocityTracker.recycle();
			mVelocityTracker = null;
		}
	}

	private void doAnimation() {
		if (mAnimating) {
			incrementAnimation();
			if (mAnimationPosition >= mBottomOffset
					+ (mVertical ? getHeight() : getWidth()) - 1) {
				mAnimating = false;
				closeDrawer();
			} else if (mAnimationPosition < mTopOffset) {
				mAnimating = false;
				openDrawer();
			} else if (mExpanded == 0
					&& mAnimationPosition - mBottomOffset
							- mSecondcontentHeight < 0) {
				mAnimating = false;
				openSecondDrawer();
			} else {
				moveHandle((int) mAnimationPosition);
				mCurrentAnimationTime += ANIMATION_FRAME_DURATION;
				mHandler.sendMessageAtTime(mHandler.obtainMessage(MSG_ANIMATE),
						mCurrentAnimationTime);
			}
		}
	}

	private void incrementAnimation() {
		long now = SystemClock.uptimeMillis();
		float t = (now - mAnimationLastTime) / 1000.0f; // ms -> s
		final float position = mAnimationPosition;
		final float v = mAnimatedVelocity; // px/s
		final float a = mAnimatedAcceleration; // px/s/s
		mAnimationPosition = position + (v * t) + (0.5f * a * t * t); // px
		mAnimatedVelocity = v + (a * t); // px/s
		mAnimationLastTime = now; // ms
	}

	/**
	 * Toggles the drawer open and close. Takes effect immediately.
	 * 
	 * @see #open()
	 * @see #close()
	 * @see #animateClose()
	 * @see #animateOpen()
	 * @see #animateToggle()
	 */
	public void toggle() {
		if (mExpanded == 0) {
			openDrawer();
		} else {
			closeDrawer();
		}
		invalidate();
		requestLayout();
	}

	/**
	 * Toggles the drawer open and close with an animation.
	 * 
	 * @see #open()
	 * @see #close()
	 * @see #animateClose()
	 * @see #animateOpen()
	 * @see #toggle()
	 */
	public void animateToggle() {
		if (mExpanded == 0) {
			animateOpen();
		} else {
			animateClose();
		}
	}

	/**
	 * Opens the drawer immediately.
	 * 
	 * @see #toggle()
	 * @see #close()
	 * @see #animateOpen()
	 */
	public void open() {
		openDrawer();
		invalidate();
		requestLayout();

		sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
	}

	/**
	 * Closes the drawer immediately.
	 * 
	 * @see #toggle()
	 * @see #open()
	 * @see #animateClose()
	 */
	public void close() {
		closeDrawer();
		invalidate();
		requestLayout();
	}

	/**
	 * Closes the drawer with an animation.
	 * 
	 * @see #close()
	 * @see #open()
	 * @see #animateOpen()
	 * @see #animateToggle()
	 * @see #toggle()
	 */
	public void animateClose() {
		prepareContent();
		final OnDrawerScrollListener scrollListener = mOnDrawerScrollListener;
		if (scrollListener != null) {
			scrollListener.onScrollStarted();
		}
		animateClose(mVertical ? mContentView.getTop() : mContentView.getLeft());

		if (scrollListener != null) {
			scrollListener.onScrollEnded();
		}
	}

	/**
	 * Opens the drawer with an animation.
	 * 
	 * @see #close()
	 * @see #open()
	 * @see #animateClose()
	 * @see #animateToggle()
	 * @see #toggle()
	 */
	public void animateOpen() {
		prepareContent();
		final OnDrawerScrollListener scrollListener = mOnDrawerScrollListener;
		if (scrollListener != null) {
			scrollListener.onScrollStarted();
		}
		animateOpen(mVertical ? mContentView.getTop() : mContentView.getLeft());

		sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);

		if (scrollListener != null) {
			scrollListener.onScrollEnded();
		}
	}

	public interface onActionEndListener {

		void onActionEnd();
	}

	private onActionEndListener monActionEndListener = null;

	public void SetonActionEndListener(onActionEndListener l) {
		monActionEndListener = l;
	}

	private void openSecondDrawer() {
		moveHandle(FIRST_DRAWER_OPEN);
		// mFirstContent.setVisibility(View.VISIBLE);

		if (mExpanded == 2) {
			return;
		}

		mExpanded = 2;

		if (mOnHalfOpenListener != null) {
			mOnHalfOpenListener.onHalfOpen();
		}
		VorH = 0;
		if (monActionEndListener != null)
			monActionEndListener.onActionEnd();
	}

	private void closeDrawer() {
		moveHandle(COLLAPSED_FULL_CLOSED);
		// mFirstContent.setVisibility(View.GONE);
		if (mOnDrawerCloseListener != null) {
			mOnDrawerCloseListener.onDrawerClosed();
		}
		if (mExpanded == 0) {
			return;
		}

		mExpanded = 0;

		VorH = 0;
		if (monActionEndListener != null)
			monActionEndListener.onActionEnd();
	}

	private void openDrawer() {
		moveHandle(EXPANDED_FULL_OPEN);
		// mFirstContent.setVisibility(View.VISIBLE);

		if (mExpanded == 1) {
			return;
		}

		mExpanded = 1;

		if (mOnDrawerOpenListener != null) {
			mOnDrawerOpenListener.onDrawerOpened();
		}
		VorH = 0;
		if (monActionEndListener != null)
			monActionEndListener.onActionEnd();
	}

	/**
	 * Sets the listener that receives a notification when the drawer becomes
	 * open.
	 * 
	 * @param onDrawerOpenListener
	 *            The listener to be notified when the drawer is opened.
	 */
	public void setOnDrawerOpenListener(
			OnDrawerOpenListener onDrawerOpenListener) {
		mOnDrawerOpenListener = onDrawerOpenListener;
	}

	/**
	 * Sets the listener that receives a notification when the drawer becomes
	 * close.
	 * 
	 * @param onDrawerCloseListener
	 *            The listener to be notified when the drawer is closed.
	 */
	public void setOnDrawerCloseListener(
			OnDrawerCloseListener onDrawerCloseListener) {
		mOnDrawerCloseListener = onDrawerCloseListener;
	}

	/**
	 * Sets the listener that receives a notification when the drawer starts or
	 * ends a scroll. A fling is considered as a scroll. A fling will also
	 * trigger a drawer opened or drawer closed event.
	 * 
	 * @param onDrawerScrollListener
	 *            The listener to be notified when scrolling starts or stops.
	 */
	public void setOnDrawerScrollListener(
			OnDrawerScrollListener onDrawerScrollListener) {
		mOnDrawerScrollListener = onDrawerScrollListener;
	}

	/**
	 * Returns the handle of the drawer.
	 * 
	 * @return The View reprenseting the handle of the drawer, identified by the
	 *         "handle" id in XML.
	 */

	/**
	 * Returns the content of the drawer.
	 * 
	 * @return The View reprenseting the content of the drawer, identified by
	 *         the "content" id in XML.
	 */

	/**
	 * Unlocks the SlidingDrawer so that touch events are processed.
	 * 
	 * @see #lock()
	 */
	public void unlock() {
		mLocked = false;
	}

	/**
	 * Locks the SlidingDrawer so that touch events are ignores.
	 * 
	 * @see #unlock()
	 */
	public void lock() {
		mLocked = true;
	}

	/**
	 * Indicates whether the drawer is currently fully opened.
	 * 
	 * @return 0 if the drawer is close, 2 if the drawer is half-open, 1 means
	 *         totally open.
	 */
	public int getOpenState() {
		return mExpanded;
	}

	public double getSecondH() {
		return mSecondcontentHeight;
	}

	public double getHandlerH() {
		return mHandleHeight;
	}

	public double getFirstH() {
		return mfirstcontentHeight;
	}

	/**
	 * Indicates whether the drawer is scrolling or flinging.
	 * 
	 * @return True if the drawer is scroller or flinging, false otherwise.
	 */
	public boolean isMoving() {
		return mTracking || mAnimating;
	}

	private class DrawerToggler implements OnClickListener {
		public void onClick(View v) {
			if (mLocked) {
				return;
			}
			// mAllowSingleTap isn't relevant here; you're *always*
			// allowed to open/close the drawer by clicking with the
			// trackball.

			if (mAnimateOnClick) {
				animateToggle();
			} else {
				toggle();
			}
		}
	}

	private class SlidingHandler extends Handler {
		public void handleMessage(Message m) {
			switch (m.what) {
			case MSG_ANIMATE:
				doAnimation();
				break;
			}
		}
	}
	
	//分页监听
	public interface OnScreenChangeListener {
		void onScreenChange(int currentIndex);
	}

	private OnScreenChangeListener onScreenChangeListener;

	public void setOnScreenChangeListener(
			OnScreenChangeListener onScreenChangeListener) {
		this.onScreenChangeListener = onScreenChangeListener;
	}
	
	
	//动态数据监听
	public interface OnScreenChangeListenerDataLoad {
		void onScreenChange(int currentIndex);
	}
	private OnScreenChangeListenerDataLoad onScreenChangeListenerDataLoad;

	public void setOnScreenChangeListenerDataLoad(OnScreenChangeListenerDataLoad onScreenChangeListenerDataLoad) {
		this.onScreenChangeListenerDataLoad = onScreenChangeListenerDataLoad;
	}
}